/*
 * 版权所有 (C) 2001-2014 深圳市艾派应用系统有限公司。保留所有权利。
 * 版本：
 * 修改记录：
 *		1、2014-10-14，tfl创建。 
 */
package com.oauth.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 常用加密算法工具类
 * @author Administrator
 *
 */
public class LoginEncryptUtils {
    public static final String key1 = "szicity20131119";// 秘钥，公积金、港澳签注
    public static final String key2 = "shebao_ipi_key";// 秘钥，社保

    /**
     * 用MD5算法进行加密
     * 
     * @param str
     *            需要加密的字符串
     * @return MD5加密后的结果
     */
    public static String encodeMD5String(String str) {
        return encode(str, "MD5");
    }

    /**
     * 用SHA算法进行加密
     * 
     * @param str
     *            需要加密的字符串
     * @return SHA加密后的结果
     */
    public static String encodeSHAString(String str) {
        return encode(str, "SHA");
    }

    /**
     * 用base64算法进行加密
     * 
     * @param str
     *            需要加密的字符串
     * @return base64加密后的结果
     * @throws UnsupportedEncodingException
     */
    public static String encodeBase64String(String str)
            throws UnsupportedEncodingException {
        Base64Encoder encoder = new Base64Encoder();
        return encoder.encode(str.getBytes("UTF-8"));
    }

    /**
     * 用base64算法进行解密
     * 
     * @param str
     *            需要解密的字符串
     * @return base64解密后的结果
     * @throws IOException
     */
//    public static String decodeBase64String(String str) throws IOException {
//        BASE64Decoder encoder = new BASE64Decoder();
//        return new String(encoder.decodeBuffer(str), "UTF-8");
//    }

    private static String encode(String str, String method) {
        MessageDigest md = null;
        String dstr = null;
        try {
            md = MessageDigest.getInstance(method);
            md.update(str.getBytes());
            dstr = new BigInteger(1, md.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return dstr;
    }

    /**
     * 加密算法
     * 
     * @param key
     * @param user
     * @param isReplace
     *            是否替换"="号
     * @return
     * @throws IOException
     */
    public static String encodeString(String key, String user, boolean isReplace)
            throws IOException {
        // String user = "210105197304114938|20131120|20413700964";
        key = encodeMD5String(key);// 第一次MD5加密
        String keya = key.substring(0, 16).toUpperCase();// 截取新密匙的前16位并大写
        int keyLen = key.length();// 获取两次"key"MD5加密后的长度
        int strLen = user.length();
        int[] rndkey = new int[128];
        // 生成128个加密因子 （按密匙中单个字符的ASCII 值）
        for (int i = 0; i < rndkey.length; i++) {
            rndkey[i] = (int) key.charAt(i % keyLen);
        }
        StringBuffer sb = new StringBuffer();
        // 用字条串的每个字符ASCII值和加密因子里的（当前循环次数*字符串长度 求于 128） 按位异或 最后 ASCII 值返回字符
        for (int i = 0; i < strLen; i++) {
            sb.append((char) (((int) user.charAt(i)) ^ rndkey[i * strLen % 128]));
        }
        if (isReplace)
            // base64加密后并替换"="后的字符
            return keya + encodeBase64String(sb.toString()).replace("=", "");
        else
            return keya + encodeBase64String(sb.toString());
    }

    /**
     * 解密算法
     * 
     * @param resultTmp
     * @return
     * @throws IOException
     */
//    public static String decodeString(String key, String encodeResultTmp)
//            throws Exception {
//        if (encodeResultTmp == null) {
//            return "";
//        }
//        key = encodeMD5String(key);// MD5加密
//        int keyLen = key.length();// 获取两次"key"MD5加密后的长度
//        // 加密结果的截取后十六位
//        String encodeResult = decodeBase64String(encodeResultTmp);
//        int strLen = encodeResult.length();
//        int[] rndkey = new int[128];
//        // 生成128个加密因子 （按密匙中单个字符的ASCII 值）
//        for (int i = 0; i < rndkey.length; i++) {
//            rndkey[i] = key.charAt(i % keyLen);
//        }
//        StringBuffer result = new StringBuffer();
//        // 用字条串的每个字符ASCII值和加密因子里的（当前循环次数*字符串长度 求于 128） 按位异或 最后 ASCII 值返回字符
//        for (int i = 0; i < strLen; i++) {
//            result.append((char) ((encodeResult.charAt(i)) ^ rndkey[i * strLen
//                    % 128]));
//        }
//        return result.toString();
//    }

    public static void main(String[] args) {
        String s = "13418463415";
        try {
            System.out.println("加密：" + encodeString(key1, s, false));
//            System.out.println("解密：" + decodeString(key1, s));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
